package ws;

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.Serializable;
import java.net.Socket;
import java.util.ArrayList;
import java.util.List;
import util.RussiaDiamondConst;
import util.RussiaDiamondUtil;
import vo.Taction;
/**
 * 文件名：RussiaDiamondClient.java
 * 版权：Copyright 2006-2012 Huawei Tech. Co. Ltd. All Rights Reserved.
 * 描述： RussiaDiamondClient.java
 * 修改人：lKF58628
 * 修改时间：2012-3-6
 * 修改内容：新增
 */

/**
 * 俄罗斯方块客户端
 * <p>
 * <p>
 * 这个框架还有重要工作没完成，没有对码流进行编解码：
 * 1、收到服务器发来的题目时，要把字符串解析成：1）本端局面的二维矩阵；2）对方局面的二维矩阵；3）本次方块类型；4）下次方块类型。
 * 2、在Play方法中把上面四个参数传进来。
 * 3、把Play方法返回的动作序列（数组，每个元素包括rotate、col、down三个值）编码成字符串，发给服务器。
 *
 * <pre>
 * </pre>
 *
 * @author lKF58628
 * @version RCS ND V100R002C02 2012-3-6
 * @since RCS ND V100R002C02
 */
public class RussiaDiamondClient implements Serializable
{

    /**
     * 序列
     */
    private static final long serialVersionUID = 6888236088787758732L;

    public static void main(String[] args) throws Exception
    {
        Socket socket = null;
        InputStream is = null;
        OutputStream os = null;
        PrintWriter writer = null;
        BufferedReader reader = null;

        try
        {
            socket = RussiaDiamondUtil.getConnect();

            socket.setSoTimeout(RussiaDiamondConst.TIME_OUT); // 5分钟超时

            is = socket.getInputStream(); // 接受服务器发送的消息
            os = socket.getOutputStream(); // 向服务器发送消息

            writer = new PrintWriter(new OutputStreamWriter(os));
            // writer = new PrintWriter(os);

            reader = new BufferedReader(new InputStreamReader(is));

            // 1、连接成功，把用户名发送给服务器
            String userName = RussiaDiamondUtil.getConnectionInfo()[0];

            writer.write(userName);
            writer.flush();

            System.out.println("游戏者：" + userName); // 记录日志

            // 开始玩
            while (true)
            {
                // 客户端接受服务器的数据报
                String str = reader.readLine();

                System.out.println("从服务端接受的内容是：" + str);

                // 只要有值，就不断的循环进行游戏
                if (null != str && 0 != str.length())
                {
                    // 玩家结束反馈结果
                    String resultString = EncodedPlay(str);

                    // 发送给服务器
                    writer.write(resultString);
                    writer.flush();
                }
                else
                {
                    break;
                }
            }

            // 释放资源
            writer.close();
            reader.close();
            os.close();
            is.close();
            socket.close();
        }

        catch (Exception e)
        {
            e.printStackTrace();

            System.out.println("unknow error!");
        }
    }

    /**
     *
     * 编解码*
     * 000010000000001000000000110000000000000000000000000000000000000000000000000
     * 000000000000000000000000000000000000000000000000000000000000000000000000000
     * 000000000000000000000000000000000000000000000000000000000000000000000000000
     * 000000000000000000000000000000000000000000000000000000000000000000000000000
     * 000000000000000000000000000000000000000000000000000000000000000000000000000
     * 000000000000000000000000014
     *
     * @param inString
     * @return
     */
    public static String EncodedPlay(String inString)
    {
        List<Taction> listData = new ArrayList<Taction>();

        // 最后两位一个是当前的方块，一个是下个方块
        String operateDiamond = inString.substring(
                RussiaDiamondConst.BOTH_FULL_DATA_NUMBER, inString.length());
        // 当前的方块
        int currentBlock = Integer.parseInt(operateDiamond.substring(0, 1));

        // 下个方块
        int nextBlock = Integer.parseInt(operateDiamond.substring(1, 2));

        String dataMineString = inString.substring(0,
                RussiaDiamondConst.ONE_PART_FULL_DATA_NUMBER);

        String rivalDataString = inString.substring(
                RussiaDiamondConst.ONE_PART_FULL_DATA_NUMBER,
                RussiaDiamondConst.BOTH_FULL_DATA_NUMBER);

        String[][] mineData = new String[RussiaDiamondConst.HEIGHT][RussiaDiamondConst.WIDTH];

        for (int i = 0; i < RussiaDiamondConst.HEIGHT; i++)
        {
            for (int j = 0; j < RussiaDiamondConst.WIDTH; j++)
            {
                mineData[i][j] = dataMineString.substring(10 * i + j, 10 * i
                        + j + 1);
                System.out.print(mineData[i][j]);
            }
            System.out.println();
        }

        // System.out.println("mineData = " + mineData.toString());

        String[][] rivalData = new String[RussiaDiamondConst.HEIGHT][RussiaDiamondConst.WIDTH];

        for (int i = 0; i < RussiaDiamondConst.HEIGHT; i++)
        {
            for (int j = 0; j < RussiaDiamondConst.WIDTH; j++)
            {
                rivalData[i][j] = rivalDataString.substring(10 * i + j, 10 * i
                        + j + 1);
            }
        }

        System.out.println("rivalData = " + rivalData.toString());

        // 游戏者自己实现核心算法
        listData = play(mineData, rivalData, currentBlock, nextBlock);

        // 解析玩家反馈的结果并且融错
        String resultStr = RussiaDiamondUtil.encodeListData(listData);

        System.out.println("resultStr = " + resultStr);

        return resultStr;
    }

    /**
     * 游戏者实现play方法(待实现......)
     *
     * @param mineData
     *            本端局面的二维矩阵
     * @param rivalData
     *            对方局面的二维矩阵
     * @param currentBlock
     *            本次方块类型
     * @param nextBlock
     *            下次方块类型
     * @return List<Taction> 动作序列（数组，每个元素包括rotate、col、down三个值）
     */
    public static List<Taction> play(String[][] mineData, String[][] rivalData,
            int currentBlock, int nextBlock)
    {

        List<Taction> list = new ArrayList<Taction>();

        Taction ta = new Taction();
        int col = (int) (Math.random() * 7);// 产生0-6的整数随机数
        ta.setColumn(col);

        int rot = (int) (Math.random() * 3);// 产生0-3的整数随机数
        ta.setRotate(rot);

        ta.setDown("00");

        // Taction ta2 = new Taction();
        // int col2 = (int) (Math.random() * 9);// 产生0-9的整数随机数
        // ta2.setColumn(col2);
        //
        // int rot2 = (int) (Math.random() * 3);// 产生0-3的整数随机数
        // ta2.setRotate(rot2);
        //
        // ta2.setDown("00");

        list.add(ta);
        // list.add(ta2);

        return list;
    }
}
